package com.ibeetl.admin.core.web;

import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.file.FileItem;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.DateUtil;
import com.ibeetl.admin.core.util.FileUtil;
import com.ibeetl.admin.core.util.UUIDUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;

@Controller
public class FileSystemContorller {
	private final Log log = LogFactory.getLog(this.getClass());
	
	@Autowired
	CorePlatformService platformService ;
	
	private static final String MODEL = "/core/file";
	
	/*附件类操作*/
	@PostMapping(MODEL + "/uploadAttachment.json")
    @ResponseBody
    public JsonResult uploadFile(@RequestParam("file") MultipartFile file,String batchFileUUID,String bizType,String bizId, String title, String url) throws IOException {
        if(file.isEmpty()) {
            return JsonResult.fail();
        }
        CoreUser user = platformService.getCurrentUser();
        CoreOrg  org = platformService.getCurrentOrg();
        FileItem fileItem = fileService.createFileItem(file.getOriginalFilename(), title, url, bizType, bizId, user.getId(), org.getId(), batchFileUUID,null);
        OutputStream os = fileItem.openOutpuStream();
        FileUtil.copy(file.getInputStream(), os);
        return JsonResult.success(fileItem);
    }
    
    @PostMapping(MODEL + "/deleteAttachment.json")
    @ResponseBody
    public JsonResult deleteFile(Long fileId,String batchFileUUID ) throws IOException {
        fileService.removeFile(fileId, batchFileUUID);
		this.platformService.clearConfigCache();
        return JsonResult.success();
    }
    
    //弹出对话框让用户下载具体文件
    @GetMapping(MODEL + "/download/{fileId}/{batchFileUUID}/{name}")
    public ModelAndView download(HttpServletResponse response,@PathVariable Long fileId,@PathVariable  String batchFileUUID ) throws IOException {
        FileItem item = fileService.getFileItemById(fileId,batchFileUUID);
        //Content-Disposition属性有两种类型:inline 和 attachment
        //inline ：将文件内容直接显示在页面
        //attachment：弹出对话框让用户下载具体文件
        response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(item.getName(),"UTF-8"));
        item.copy(response.getOutputStream());
        return null;
    }
    
    //将文件内容直接显示在页面
    @GetMapping(MODEL + "/inline/{fileId}/{name}")
    public ModelAndView inline(HttpServletResponse response,@PathVariable Long fileId) throws IOException {
        FileItem item = fileService.getFileItemById(fileId);
        //Content-Disposition属性有两种类型:inline 和 attachment
        //inline ：将文件内容直接显示在页面
        //attachment：弹出对话框让用户下载具体文件
        response.setHeader("Content-Disposition", "inline; filename="+URLEncoder.encode(item.getName(),"UTF-8"));
        item.copy(response.getOutputStream());
        return null;
    }
    //将文件内容直接显示在页面
	@GetMapping(MODEL + "/inline/{fileId}")
	public ModelAndView inline1(HttpServletResponse response,@PathVariable Long fileId) throws IOException {
	    FileItem item = fileService.getFileItemById(fileId);
	    //Content-Disposition属性有两种类型:inline 和 attachment
	    //inline ：将文件内容直接显示在页面
	    //attachment：弹出对话框让用户下载具体文件
	    response.setHeader("Content-Disposition", "inline; filename="+URLEncoder.encode(item.getName(),"UTF-8"));
	    item.copy(response.getOutputStream());
	    return null;
	}
    
	/*execl 导入导出*/
	
	@Autowired
	FileService fileService;
	@GetMapping(MODEL + "/get.do")
	public ModelAndView index(HttpServletResponse response,String id) throws IOException {
	     String path = id;
		 response.setContentType("text/html; charset = UTF-8");  
		 FileItem fileItem = fileService.loadFileItemByPath(path);
		 response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(fileItem.getName(), "UTF-8"));  
		 fileItem.copy(response.getOutputStream());
		 if(fileItem.isTemp()) {
		     fileItem.delete();
		 }
		 return null;
	}
	
	@GetMapping(MODEL + "/downloadTemplate.do")
    public ModelAndView dowloadTemplate(HttpServletResponse response,String path) throws IOException {
         response.setContentType("text/html; charset = UTF-8");  
         int start1 = path.lastIndexOf("\\");
         int start2 = path.lastIndexOf("/");
         if(start2>start1) {
             start1 = start2;
         }
         String file = path.substring(start1+1);
         response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(file,"UTF-8"));  
         InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("excelTemplates/"+path);
         FileUtil.copy(input, response.getOutputStream());
         return null;
    }
	
   @GetMapping(MODEL + "/simpleUpload.do")
    public ModelAndView simpleUploadPage(String uploadUrl,String templatePath,String fileType) throws IOException {
       ModelAndView view = new ModelAndView("/common/simpleUpload.html");
       view.addObject("uploadUrl",uploadUrl);
       view.addObject("templatePath",templatePath);
       view.addObject("fileType",fileType);
      
       return view;
   }
   
   /*kindEditor 文件上传*/
	@PostMapping(MODEL + "/kindEditorUpload.json")
	@ResponseBody
   public String kindEditorUpload(@RequestParam("imgFile") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
		/**
		 * KindEditor JSP
		 * 
		 * 本JSP程序是演示程序，建议不要直接在实际项目中使用。
		 * 如果您确定直接使用本程序，使用之前请仔细确认相关安全设置。
		 * 
		 */
		
		String path = File.separator + "attached";
		//定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,mp4");
		extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,pdf");
		
		//最大文件大小
		long maxSize = 50000000;
		
		response.setContentType("text/html; charset=UTF-8");
		
		if(!ServletFileUpload.isMultipartContent(request)){
			return getKindError("请选择文件。");
		}
		
		String dirName = request.getParameter("dir");
		if (dirName == null) {
			dirName = "image";
		}
		
		String fileName = file.getResource().getFilename();
		//检查文件大小
		if(file.getSize() > maxSize){
			return getKindError("上传文件大小超过限制。");
		}
		//检查扩展名
		String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
			return getKindError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");
		}
		
		String uuid = UUIDUtil.uuid();
		//保存路径在createFileItem里面
		FileItem fileItem = fileService.createFileItem(file.getOriginalFilename(), null, null, "kindEditorUpload", null, null, null, uuid,null);
        OutputStream os = fileItem.openOutpuStream();
        FileUtil.copy(file.getInputStream(), os);
        //"http://" + window.location.host+"/core/file/download/"+fileId+"/${batchFileUUID}/"+fileName;
		JSONObject obj = new JSONObject();
		try {
			obj.put("error", 0);
			obj.put("url", "/core/file/download/" + fileItem.getId() + "/" + uuid + "/" + fileName);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return obj.toString();
   }
	
	
	/*kindEditor 文件上传   如果在生产环境中，用这个方法可以。如果在开发环境中，重启项目后，保存的文件会被删除*/
	@PostMapping(MODEL + "/kindEditorUploadTest.json")
	@ResponseBody
   public String kindEditorUploadTest(@RequestParam("imgFile") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
		/**
		 * KindEditor JSP
		 * 
		 * 本JSP程序是演示程序，建议不要直接在实际项目中使用。
		 * 如果您确定直接使用本程序，使用之前请仔细确认相关安全设置。
		 * 
		 */
		
		//文件保存目录路径,System.getProperty("user.dir")是获得当前工程路径
		String savePath = request.getServletContext().getRealPath("/");

		//文件保存目录URL
		String saveUrl  = request.getContextPath() + "/";
		
		String path = File.separator + "attached";
		//定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,mp4");
		extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
		
		//最大文件大小
		long maxSize = 50000000;
		
		response.setContentType("text/html; charset=UTF-8");
		
		if(!ServletFileUpload.isMultipartContent(request)){
			return getKindError("请选择文件。");
		}
		
		String dirName = request.getParameter("dir");
		if (dirName == null) {
			dirName = "image";
		}
		path += File.separator + dirName + File.separator + DateUtil.now("yyyyMMdd");
		
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");

		String fileName = file.getResource().getFilename();
		
		//检查文件大小
		if(file.getSize() > maxSize){
			return getKindError("上传文件大小超过限制。");
		}
		//检查扩展名
		String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
			return getKindError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");
		}
		try{
			savePath = savePath + path + File.separator + fileName;
			saveUrl = saveUrl + path + File.separator + fileName;
			saveUrl = saveUrl.replace(File.separator, "/");
			File f = new File(savePath);
			f.getParentFile().mkdirs();
			FileOutputStream fos = new FileOutputStream(f);
	        FileUtil.copy(file.getInputStream(), fos);
		}catch(Exception e){
			return getKindError("上传文件失败。");
		}

		JSONObject obj = new JSONObject();
		try {
			obj.put("error", 0);
			obj.put("url", saveUrl);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return obj.toString();
   }
	
   
   private String getKindError(String message) {
		JSONObject obj = new JSONObject();
		try {
			obj.put("error", 1);
			obj.put("message", message);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(obj.toString());
		return obj.toString();
	}
   
   
   /*附件类操作*/
   @PostMapping(MODEL + "/layuiUpload.json")
   @ResponseBody
   public JsonResult layuiUpload(@RequestParam("file") MultipartFile file,String batchFileUUID,String bizType,String bizId, String title, String url) throws IOException {
       if(file.isEmpty()) {
           return JsonResult.fail();
       }
       FileItem fileItem = fileService.createFileItem(file.getOriginalFilename(), null, null, "layuiUpload", null, null, null, UUIDUtil.uuid(),null);
       OutputStream os = fileItem.openOutpuStream();
       FileUtil.copy(file.getInputStream(), os);
       fileItem.setPath("/core/file/inline/" + fileItem.getId() + "/" + fileItem.getName());
       return JsonResult.success(fileItem);
   }
}
